//
// Created by hjie on 23-10-3.
//

#pragma once

#include <cstring>
#include <functional>
#include <string>
#include <vector>
#include <map>

extern "C"
{
#include <libavformat/avio.h>
#include <libavformat/avformat.h>
#include <libavcodec/packet.h>
#include <libavutil/frame.h>
#include <libavutil/pixfmt.h>
#include <libavutil/rational.h>
#include <libavcodec/avcodec.h>
};

using ConfigCallback=std::function<void(AVCodecContext * codec_ctx)>;

class InputFileData;
class OutputFileData;

struct VideoParamConfig
{
    std::string m_codec_name;
    std::string m_hw_name;
    bool        m_encode{false};

    int         m_width{0};
    int         m_height{0};
    AVFrame  *  m_frame{nullptr};
    ConfigCallback m_config_callback;
    bool        m_copy_decoder_param{false};
};

struct AudioParamConfig
{
    std::string m_codec_name;
    bool        m_encode{false};
    int         m_format{-1};
    int         m_channel{0};
    int         m_channel_layout{0};
    int         m_sample_rate;
    AVFrame     * m_frame{nullptr};
    ConfigCallback m_config_callback;
    bool        m_copy_decoder_param{false};
};

class CodecConfig
{
public:
    CodecConfig();
public:
    void SetTimebase(AVRational timebase);
    void SetRealBaseFrameRate(AVRational frmae_rate);
    void SetAvgFrameRate(AVRational & frmae_rate);
    void SetCodecName(const std::string & name);
    void SetWidth(int width);
    void SetHeight(int height);
    void SetWidthHeight(int w, int h);
    void SetFormatAndSwFormat(int format, int sw_format);
    void SetBitrate(int bit_rate);
    void SetHasBFrame(int num);
public:
    int Width()
    {
        return m_width;
    }
    int Height()
    {
        return m_height;
    }
    AVRational Timebase()
    {
        return m_timebase;
    }
    int PixFmt()
    {
        return m_format;
    }
private:
    friend class InputFileData;
    friend class OutputFileData;
    // public
    std::string m_codec_name;
    // public
    AVRational m_timebase;
    AVRational m_r_frame_rate;
    AVRational m_a_frame_rate;

    int m_bit_rate;
    // video
    int m_width{0};
    int m_height{0};
    int m_format;
    int m_sw_format;
    int m_has_b_frame;
    // audio
    int m_sample{0};
public:
    VideoParamConfig m_video_config;
    AudioParamConfig m_audio_config;
};


